#pragma once
#include <cmath>
#include "Vectors.h"

//#define MULTI_DEBUG

#ifdef MULTI_DEBUG
static int g_scrHeight = 600;
static int g_scrWidth = 800;
#else
static int g_scrHeight	= 720;
static int g_scrWidth	= 1280;
#endif

static float g_AtmSpin	= 0.003f; //In MS - Determines spinspeed of the AtmoSphere

#define NETWORK_DEFAULT_PORT 7777

//Draw modes
//#define WIREFRAME
//#define SILHOUETTE

#define ITEM_NULL		0
#define ITEM_EMPTY		1
#define ITEM_EQUIPPABLE 2
#define ITEM_CONSUMABLE 3
#define ITEM_PROJECTILE 4
#define ITEM_MATERIAL	5

#define maxInventoryMenu 84
#define maxEquipmentMenu 16
#define maxCrafTableMenu 128


//====Collision

struct pointQuad	//For Precision
{
	float x,y,width,height;
	pointQuad():x(0),y(0),width(0),height(0){};
	pointQuad(float x,float y,float Width,float Height)
		:x(x),y(y),width(Width),height(Height){};
	inline float getMinY()const{return y;}
	inline float getMinX()const{return x;}
	inline float getMaxY()const{return y + height;}
	inline float getMaxX()const{return x + width;}
};
struct Quad		//For Memory
{
	short x,y,width,height;
	Quad():x(0),y(0),width(0),height(0){};
	Quad(short x,short y,short Width,short Height)
		:x(x),y(y),width(Width),height(Height){};
	inline short getMinY()const{return y;}
	inline short getMinX()const{return x;}
	inline short getMaxY()const{return y + height;}
	inline short getMaxX()const{return x + width;}
	void set(short x,short y,short Width,short Height)
	{
		this->x = x; this->y = y; this->width = Width; this->height = Height;}
	bool isColliding(Quad const & q)
	{
		return 
			!( getMinY() > q.getMaxY()		// this is below q
			|| getMaxY() < q.getMinY()		// this is above q
			|| getMinX() > q.getMaxX()		// this is right of q
			|| getMaxX() < q.getMinX());	// this is left of q
	}
	bool isColliding(pointQuad const & q)
	{
		return 
			!( getMinY() > q.getMaxY()		// this is below q
			|| getMaxY() < q.getMinY()		// this is above q
			|| getMinX() > q.getMaxX()		// this is right of q
			|| getMaxX() < q.getMinX());	// this is left of q
	}
	bool isColliding(short x, short y)
	{
		return 
			!( getMinY() > y		// this is below
			|| getMaxY() < y		// this is above
			|| getMinX() > x		// this is right
			|| getMaxX() < x);		// this is left

	};
	bool isColliding(Vector2D point)
	{
		return 
			!( getMinY() > point.y		// this is below
			|| getMaxY() < point.y		// this is above
			|| getMinX() > point.x		// this is right
			|| getMaxX() < point.x);		// this is left

	};
	pointQuad convertToFloats()
	{
		return pointQuad(float(x),float(y),float(width),float(height));
	}


};




enum CollideSpots
{
	DIR_UP,
	DIR_SIDE,
	DIR_DOWN,
	DIR_LEFT,
	DIR_RIGHT,
	//	DIR_BODY,
	DIR_SIZE
};

enum SoundEffects
{
	WAV_ZOMDEATH,
	WAV_PLAYERDEATH,
	WAV_DRONEDEATH,
	WAV_SWOOSH,
	WAV_GUNSHOT,
	WAV_FIREBALL,
	WAV_ERROR,
	WAV_CRUMBLE,
	WAV_STIM,
	WAV_MAXSOUNDS
};

//=====Physics
inline float calcPos(float init, float initVel, float time, float accel)
{
	//f(t) = f(0) + v(0)t + 1/2at^2
	return (float)(init + initVel * time + 0.5 * accel * time * time);
};
inline float quadFormula(float A, float B, float C)
{
	//Quadratic formula really has two answers but for this project
	//One answer will be negative and the other should be positive
	float ans1 = (B * -1 + sqrt((B * B) - (4 * A * C))) / (2 * A);
	float ans2 = (B * -1 - sqrt((B * B) - (4 * A * C))) / (2 * A);

	//returns the larger (positive) value
	if(ans1 > 0)
		return ans1;
	return ans2;
};
inline float convertToRad(float angle)
{
	return (float)(angle*(3.14159265/180));
};

#include <string>
#include <sstream>
namespace wordModify
{

	inline std::string wmIntegerToString(int i)
	{
		std::stringstream out;
		out << i;
		return out.str();
	}
		inline char* copy(std::string source)
	{
		int i = 0;
		char* destination;
		destination = new char[source.size()+1];
		for(; i < signed(source.size()); i++)
			destination[i] = source[i];
		destination[i] = '\0';
		return destination;
	}


	inline char* copy(char* destination, std::string source)
	{
		int i = 0;
		destination = new char[source.size()];
		for(; i < signed(source.size()); i++)
			destination[i] = source[i];
		destination[i] = '\0';
		return destination;
	}
	inline int   strLength(char* text)
	{
		if(!text)
			return 0;

		int i = 0;
		for(; text[i] != '\0'; i++);
		return i;
	}
	inline int   strLength(const char* text)
	{
		if(!text)
			return 0;

		int i = 0;
		for(; text[i] != '\0'; i++);
		return i;
	}
	inline char* combine(char* base, char* extension)
	{
		int size = strLength(base) + strLength(extension);
		char* newStr = new char[size+1];
		for(int i = 0; i < strLength(base); ++i)
			newStr[i] = base[i];
		for(int i = strLength(base), j = 0; i < size; ++i, ++j)
			newStr[i] = extension[j];
		newStr[size] = '\0';
		return newStr;
	}
	inline void  append(char* addTo, char*toAdd, int length)
	{
		if((strLength(addTo) + strLength(toAdd)) < length){
			int start = 0;
			int toAddCursor = 0;
			for(;addTo[start] != '\0' ; start++);
			for(;toAdd[toAddCursor]	  != '\0' ; toAddCursor++)
				addTo[start+toAddCursor] = toAdd[toAddCursor];
			addTo[start+toAddCursor] = '\0';
		}
	}
	inline void  append(char* addTo, char toAdd, int length)
	{
		if(strLength(addTo) < length-1)
		{
			int start = 0;
			for(; addTo[start] != '\0';start++);
			addTo[start] = toAdd;
			addTo[start+1] = '\0';
		}
	}
	inline void  removeLast(char* removeFrom)
	{
		int toRemove = 0;
		for(; removeFrom[toRemove] != '\0'; toRemove++);
		if(toRemove > 0)	removeFrom[toRemove-1] = '\0';
		else				removeFrom[0] = '\0';
	}
	inline char* copy(char* toCopy,int length)
	{
		int i = 0;
		char* toReturn = new char[length];
		for(; toCopy[i] != '\0';i++)
			toReturn[i] = toCopy[i];
		toReturn[i] = '\0';
		return toReturn;
	}
	inline char* copy(char* toCopy)
	{
		int i = 0;
		char* toReturn = new char[strlen(toCopy)];
		for(; toCopy[i] != '\0';i++)
			toReturn[i] = toCopy[i];
		toReturn[i] = '\0';
		return toReturn;
	}
	inline void copyIntoExisting(char* str1, const char* str2)
	{
		// do not alter this function
			int i = 0;
			for(; str2[i]; ++i)
				str1[i] = str2[i];
			str1[i] = '\0';
	}
	inline char* copyWord(char* toCopy)
	{
		int i = 0, length = strLength(toCopy);
		char* toReturn = new char[length+1];
		for(; toCopy[i] != '\0'; i++)
			toReturn[i] = toCopy[i];
		toReturn[i] = '\0';
		return toReturn;
	}
	inline void  wipe(char* toCopy)
	{
		int x = strLength(toCopy);
		for(int i = 0; i < x; i++)
			removeLast(toCopy);
	}
	inline bool compare(char* first, char* second)
	{
		int sizeOne = strLength(first);
		int sizeTwo = strLength(second);

		if(sizeOne != sizeTwo)
			return false;

		for(int i = 0; i < strLength(first); i++) 
		{
			if(first[i] != second[i])
				return false;
		}
		return true;
	}
};

const float Gravity = -1.0f;
const int	Meter = 10;
const float PI = 3.14159265f;

